package com.duojuhe.coremodule.topo.service.impl;

import com.duojuhe.cache.SystemDictCache;
import com.duojuhe.common.annotation.DataScopeFilter;
import com.duojuhe.common.bean.DataScopeFilterBean;
import com.duojuhe.common.bean.UserTokenInfoVo;
import com.duojuhe.common.constant.DataScopeConstants;
import com.duojuhe.common.enums.SystemEnum;
import com.duojuhe.common.exception.base.DuoJuHeException;
import com.duojuhe.common.result.ErrorCodes;
import com.duojuhe.common.result.PageResult;
import com.duojuhe.common.result.ServiceResult;
import com.duojuhe.common.utils.idgenerator.UUIDUtils;
import com.duojuhe.common.utils.page.PageHelperUtil;
import com.duojuhe.coremodule.BaseService;
import com.duojuhe.coremodule.system.entity.SystemDict;
import com.duojuhe.coremodule.topo.entity.TopoElementClass;
import com.duojuhe.coremodule.topo.entity.TopoElementInfo;
import com.duojuhe.coremodule.topo.mapper.TopoElementClassMapper;
import com.duojuhe.coremodule.topo.mapper.TopoElementInfoMapper;
import com.duojuhe.coremodule.topo.pojo.dto.elementclass.*;
import com.duojuhe.coremodule.topo.service.TopoElementClassService;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import javax.annotation.Resource;
import org.springframework.stereotype.Service;
import tk.mybatis.mapper.entity.Example;

import java.util.Date;
import java.util.List;

@Slf4j
@Service
public class TopoElementClassServiceImpl extends BaseService implements TopoElementClassService {
    @Resource
    private SystemDictCache systemDictCache;
    @Resource
    private TopoElementClassMapper topoElementClassMapper;
    @Resource
    private TopoElementInfoMapper topoElementInfoMapper;


    /**
     * 【分页查询】分页查询拓扑图元分类分类list
     * @param req
     * @return
     */
    @DataScopeFilter
    @Override
    public ServiceResult<PageResult<List<QueryTopoElementClassPageRes>>> queryTopoElementClassPageResList(QueryTopoElementClassPageReq req) {
        PageHelperUtil.orderByAndStartPage(req, "sort desc,createTime desc, classId desc");
        List<QueryTopoElementClassPageRes> list = topoElementClassMapper.queryTopoElementClassPageResList(req);
        for (QueryTopoElementClassPageRes res:list){
            SystemDict dictStatus = systemDictCache.getSystemDictByDictCode(res.getStatusCode());
            res.setStatusName(dictStatus.getDictName());
            res.setStatusColor(dictStatus.getDictColor());
        }
        return PageHelperUtil.returnServiceResult(req,list);
    }

    /**
     * 查询正常可用的拓扑图元分类
     * @return
     */
    @DataScopeFilter(dataScope = DataScopeConstants.TENANT_ALL_DATA)
    @Override
    public ServiceResult<List<SelectTopoElementClassRes>> queryNormalSelectTopoElementClassResList(DataScopeFilterBean dataScope) {
        PageHelperUtil.defaultOrderBy("sort desc,createTime desc,classId desc");
        return ServiceResult.ok(topoElementClassMapper.querySelectTopoElementClassResListByStatus(dataScope, SystemEnum.STATUS.NORMAL.getKey()));
    }

    /**
     * 【保存】拓扑图元分类分类信息
     * @param req
     * @return
     */
    @Override
    public ServiceResult saveTopoElementClass(SaveTopoElementClassReq req) {
        //当前登录人
        UserTokenInfoVo userTokenInfoVo = getCurrentLoginUserInfoDTO();
        //分类id
        String classId = UUIDUtils.getUUID32();
        //当前时间
        Date nowDate = new Date();
        TopoElementClass elementClass = new TopoElementClass();
        elementClass.setClassId(classId);
        elementClass.setClassName(req.getClassName());
        elementClass.setCreateTime(nowDate);
        elementClass.setCreateUserId(userTokenInfoVo.getUserId());
        elementClass.setUpdateTime(nowDate);
        elementClass.setExpandFlag(req.getExpandFlag());
        elementClass.setUpdateUserId(userTokenInfoVo.getUserId());
        elementClass.setSort(req.getSort());
        elementClass.setStatusCode(req.getStatusCode());
        elementClass.setCreateDeptId(userTokenInfoVo.getCreateDeptId());
        elementClass.setTenantId(userTokenInfoVo.getTenantId());
        topoElementClassMapper.insertSelective(elementClass);
        return ServiceResult.ok(classId);
    }

    /**
     * 【修改】拓扑图元分类分类信息
     * @param req
     * @return
     */
    @Override
    public ServiceResult updateTopoElementClass(UpdateTopoElementClassReq req) {
        String classId = req.getClassId();
        TopoElementClass elementClassOld = topoElementClassMapper.selectByPrimaryKey(classId);
        if (elementClassOld == null) {
            return ServiceResult.fail(ErrorCodes.PARAM_ERROR);
        }
        //当前登录人
        UserTokenInfoVo userTokenInfoVo = getCurrentLoginUserInfoDTO();
        //当前时间
        Date nowDate = new Date();
        TopoElementClass elementClass = new TopoElementClass();
        elementClass.setClassId(classId);
        elementClass.setClassName(req.getClassName());
        elementClass.setUpdateTime(nowDate);
        elementClass.setExpandFlag(req.getExpandFlag());
        elementClass.setUpdateUserId(userTokenInfoVo.getUserId());
        elementClass.setSort(req.getSort());
        elementClass.setStatusCode(req.getStatusCode());
        topoElementClassMapper.updateByPrimaryKeySelective(elementClass);
        return ServiceResult.ok(classId);
    }

    /**
     * 【删除】根据拓扑图元分类分类ID删除拓扑分类，注意一次仅能删除一个拓扑分类，存在绑定关系的则不能删除
     * @param req
     * @return
     */
    @Override
    public ServiceResult deleteTopoElementClassByClassId(TopoElementClassIdReq req) {
        String classId = req.getClassId();
        TopoElementClass elementClass = topoElementClassMapper.selectByPrimaryKey(classId);
        if (elementClass == null) {
            return ServiceResult.fail(ErrorCodes.PARAM_ERROR);
        }
        //检查是否关联图元信息
        checkRelationTopoElementInfo(classId);
        //删除对象
        topoElementClassMapper.deleteByPrimaryKey(classId);
        return ServiceResult.ok(classId);
    }

    /**
     * 【私有方法，辅助其他接口方法使用】 检查分类是否存在关联图元
     */
    private void checkRelationTopoElementInfo(String classId) {
        if (StringUtils.isBlank(classId)){
            throw new DuoJuHeException(ErrorCodes.TOPO_ELEMENT_CLASS_RELATION_ELEMENT_NOT_DELETE);
        }
        Example example = new Example(TopoElementInfo.class);
        Example.Criteria criteria = example.createCriteria();
        criteria.andEqualTo("classId", classId);
        if (topoElementInfoMapper.selectByExample(example).size()>0){
            throw new DuoJuHeException(ErrorCodes.TOPO_ELEMENT_CLASS_RELATION_ELEMENT_NOT_DELETE);
        }
    }
}
